package com.game.majiang.vo;

import java.sql.SQLException;
import java.sql.Types;
import java.util.*;
import java.util.stream.Collectors;

import javax.sql.rowset.CachedRowSet;

import com.game.majiang.algorithm.PaperCard;
import com.game.majiang.config.LogManager;
import com.game.server.db.Parameter;
import com.game.server.db.ParameterType;
import com.game.server.db.SqlHelperwrite;

import lombok.Data;
import lombok.Getter;
import org.luna.datastruct.set.RandomReadWriteSet;

public class GrateCardsVo {

  @Getter
  private final RandomReadWriteSet<List<PaperCard>> cards = new RandomReadWriteSet<>();

  private static GrateCardsVo instance = new GrateCardsVo();

  private GrateCardsVo() {
    LogManager.getInstance().Log("GrateCardsVo 初始化");
    cards.clear();
    cards.addAll(obtainsCards());
  }

  public static GrateCardsVo getInstance() {
    return null != instance ? instance: (new GrateCardsVo());
  }

  /**
   *   public RandomReadWriteSet<List<PaperCard>> getCards() {
   *     if(cards.isEmpty()) cards.addAll(obtainsCards());
   *     return cards;
   *   }
   */

  /**
   * 添加好牌组
   * @param types
   * @param num
   * @return
   */
  public boolean addGrateCards(List<Integer> types, List<Integer> num) {
    if(types.size() % 4 != 0 || num.size() % 4 != 0 || types.size() != num.size()) {
      return false;
    }
    List<Parameter> params = new ArrayList<>();
    StringBuilder cmd = new StringBuilder();
    cmd.append("INSERT INTO `grate_cards_group` ( \n");
    cmd.append("`card_1st_type`, \n");
    cmd.append("`card_2nd_type`, \n");
    cmd.append("`card_3rd_type`, \n");
    cmd.append("`card_4th_type`, \n");
    cmd.append("`card_1st_num`, \n");
    cmd.append("`card_2nd_num`, \n");
    cmd.append("`card_3rd_num`, \n");
    cmd.append("`card_4th_num` \n");
    cmd.append(") VALUES \n");
    List<List<PaperCard>> newCardsList = new ArrayList<>();
    PaperCard card = new PaperCard();
    LogManager.getInstance().Log("the types is " + types);
    for(int i = 0; i < types.size(); i += 4) {
      cmd.append("( ?, ?, ?, ?, ?, ?, ?, ? )").append(",");
      params.addAll(types.subList(i, i + 4).stream()
          .map(type -> new Parameter(Types.INTEGER, type, ParameterType.Input)).collect(Collectors.toList()));
      params.addAll(num.subList(i, i + 4).stream()
          .map(n -> new Parameter(Types.INTEGER, n, ParameterType.Input)).collect(Collectors.toList()));
      List<PaperCard> newCards = new ArrayList<>();
      for(int j = i; j < i + 4; j += 1) {
        newCards.add(card.initChexuanCard(0, types.get(j), num.get(j)));
      }
      newCardsList.add(newCards);
    }
    cmd.deleteCharAt(cmd.length() - 1).append(";");
    String cmdText = cmd.toString();

    LogManager.getInstance().Log("添加牌组-最终SQL：" + cmdText);
    try {
      int result = SqlHelperwrite.execute(cmdText, params.toArray(new Parameter[0]));
      if(result > 0) {
        // 写入缓存
        cards.addAll(newCardsList);
        return true;
      } else {
        return false;
      }
    } catch(Exception e) {
      LogManager.getInstance().Log("添加牌组失败: " + e.getMessage() + "\n" + e.fillInStackTrace().toString());
      return false;
    }
  }

  /**
   * 移除指定id的好牌组
   * @param id
   * @return
   */
  public boolean removeGrateCards(int id) {
    String cmdText = "delete from grate_cards_group where id = ?";
    Parameter p1 = new Parameter(Types.INTEGER, id, ParameterType.Input);
    int result = SqlHelperwrite.execute(cmdText, new Parameter[] { p1 });
    return result > 0;
  }

  public Map<String, List<PaperCard>> queryGrateCards() {
    Map<String, List<PaperCard>> result = new HashMap<>();
    List<String> fields = Arrays.asList(
        "id", "card_1st_type", "card_2nd_type", "card_3rd_type",
        "card_4th_type", "card_1st_num", "card_2nd_num", "card_3rd_num",
        "card_4th_num"
    );
    StringBuilder cmd = new StringBuilder();
    cmd.append("SELECT \n");
    cmd.append("\t`").append(String.join("`,\n\t`", fields)).append("`\n");
    cmd.append("FROM `grate_cards_group` \n");
    String cmdText = cmd.toString();
    CachedRowSet rs = SqlHelperwrite.getResultSet(cmdText);
    try {
      while (rs.next()) {
        List<PaperCard> cards = new ArrayList<>();
        for (int i = 2; i <= 5; i += 1) {
          int cardType = rs.getInt(i);
          int cardNum = rs.getInt(i + 4);
          PaperCard card = new PaperCard();
          cards.add(card.initChexuanCard(1, cardType, cardNum));
        }
        result.put(Integer.toString(rs.getInt(1)), cards);
      }
    } catch (SQLException e) {
      LogManager.getInstance().Log("查询好牌组失败：" + e.getMessage() +
          "\n" + e.fillInStackTrace().toString());
    }
    return result;
  }

  private RandomReadWriteSet<List<PaperCard>> obtainsCards() {
    RandomReadWriteSet<List<PaperCard>> result = new RandomReadWriteSet<>();
    result.addAll(queryGrateCards().values());
    LogManager.getInstance().Log("初始化好牌组成功！" + result);
    return result;
  } 
}
